/* * Copyright (C) 2011 Ives van der Flaas * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package be.ac.ua.comp.scarletnebula.core; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.jfree.util.Log; import be.ac.ua.comp.scarletnebula.gui.NotPromptingJschUserInfo; import com.jcraft.jcterm.Connection; import com.jcraft.jcterm.Term; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.ChannelShell; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import com.jcraft.jsch.UserInfo; public class SSHCommandConnection extends CommandConnection { Session session = null; private enum LoginMethod { PASSWORD, KEY }; private SSHCommandConnection(final String address, final String username, final String keypairfilenameOrPassword, final UserInfo ui, final LoginMethod loginMethod) throws Exception { final JSch jsch = new JSch(); if (loginMethod == LoginMethod.KEY) { jsch.addIdentity(keypairfilenameOrPassword); } session = jsch.getSession(username, address, 22); final java.util.Properties config = new java.util.Properties(); config.put("compression.s2c", "zlib,none"); config.put("compression.c2s", "zlib,none"); session.setUserInfo(ui); session.setConfig(config); if (loginMethod == LoginMethod.PASSWORD) { session.setPassword(keypairfilenameOrPassword); } session.connect(); // session.rekey(); } static public SSHCommandConnection newConnectionWithPassword( final String address, final String username, final String password, final UserInfo ui) throws Exception { return new SSHCommandConnection(address, username, password, ui, LoginMethod.PASSWORD); } static public SSHCommandConnection newConnectionWithKey( final String address, final String username, final String key, final UserInfo ui) throws Exception { return new SSHCommandConnection(address, username, key, ui, LoginMethod.KEY); } @Override public String executeCommand(final String command) throws JSchException, IOException { final ChannelExec channel = (ChannelExec) session.openChannel("exec"); channel.setCommand(command); channel.setInputStream(null); channel.setErrStream(System.err); final InputStream in = channel.getInputStream(); channel.connect(); final StringBuilder result = new StringBuilder(); final byte[] tmp = new byte[1024]; while (true) { while (in.available() > 0) { final int i = in.read(tmp, 0, 1024); if (i < 0) { break; } result.append(new String(tmp, 0, i)); } if (channel.isClosed()) { Log.info("exit-status: " + channel.getExitStatus()); break; } try { Thread.sleep(1000); } catch (final Exception ee) { } } channel.disconnect(); return result.toString(); } public ChannelInputStreamTuple executeContinuousCommand(final String command) throws JSchException, IOException { final ChannelExec channel = (ChannelExec) session.openChannel("exec"); channel.setCommand(command); channel.setInputStream(null); channel.setErrStream(System.err); final InputStream in = channel.getInputStream(); channel.connect(); return new ChannelInputStreamTuple(channel, in); } @Override public void close() { session.disconnect(); } public Connection getJSchTerminalConnection() throws JSchException, IOException { final Channel channel = session.openChannel("shell"); final OutputStream out = channel.getOutputStream(); final InputStream in = channel.getInputStream(); channel.connect(); final OutputStream fout = out; final InputStream fin = in; final Channel fchannel = channel; final Connection connection = new Connection() { @Override public InputStream getInputStream() { return fin; } @Override public OutputStream getOutputStream() { return fout; } @Override public void requestResize(final Term term) { if (fchannel instanceof ChannelShell) { final int c = term.getColumnCount(); final int r = term.getRowCount(); ((ChannelShell) fchannel).setPtySize(c, r, c * term.getCharWidth(), r * term.getCharHeight()); } } @Override public void close() { fchannel.disconnect(); } }; return connection; } public static void main(final String[] args) { try { final SSHCommandConnection connection = SSHCommandConnection .newConnectionWithPassword("radix.cmi.ua.ac.be", "p080558", "somepassword", new NotPromptingJschUserInfo()); final ChannelInputStreamTuple tuple = connection .executeContinuousCommand("date"); // while [[ 1 ]]; do echo // \"incoming data\"; date; sleep 1; done"); final InputStream in = tuple.inputStream; final Channel channel = tuple.channel; System.out.println(); StringBuilder result = new StringBuilder(); final int buffersize = 1024; final byte[] tmp = new byte[buffersize]; while (true) { while (in.available() > 0) { final int i = in.read(tmp, 0, buffersize); if (i < 0) { break; } result.append(new String(tmp, 0, i)); // Start of weird shit while (result.indexOf("\n") >= 0) { final int nlPos = result.indexOf("\n"); final String before = result.substring(0, nlPos); final String after = result.substring(nlPos + 1); result = new StringBuilder(after); } } if (channel.isClosed()) { break; } try { Thread.sleep(1000); } catch (final Exception ee) { } } channel.disconnect(); } catch (final Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public class ChannelInputStreamTuple { public Channel channel; public InputStream inputStream; ChannelInputStreamTuple(final Channel channel, final InputStream inputStream) { this.channel = channel; this.inputStream = inputStream; } } }